home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / forth / pfe-0.000 / pfe-0 / pfe-0.9.13 / demo / tetris.4th < prev    next >
Encoding:
Text File  |  1994-11-04  |  8.8 KB  |  373 lines

  1. \
  2. \ tetris.4th    Tetris for terminals, redone in ANSI-Forth.
  3. \        Written 05Apr94 by Dirk Uwe Zoller, e-mail:
  4. \            duz@roxi.rz.fht-mannheim.de.
  5. \        Look&feel stolen from Mike Taylor's "TETRIS FOR TERMINALS"
  6. \
  7. \        Please copy and share this program, modify it for your system
  8. \        and improve it as you like. But don't remove this notice.
  9. \
  10. \        Thank you.
  11. \
  12. \        Changes:
  13. \
  14. \
  15.  
  16. ONLY FORTH DEFINITIONS
  17. S" FORGET-TT" DROP 1 CHARS - FIND NIP [IF] FORGET-TT [THEN]
  18. MARKER FORGET-TT
  19.  
  20. WORDLIST CONSTANT TETRIS
  21. GET-ORDER TETRIS DUP ROT 2 + SET-ORDER DEFINITIONS
  22.  
  23. DECIMAL
  24.  
  25. \ Variables, constants
  26.  
  27. BL BL 2CONSTANT EMPTY        \ an empty position
  28. VARIABLE WIPING            \ if true: wipe brick, else draw brick
  29. 2 CONSTANT COL0            \ position of the pit on screen
  30. 0 CONSTANT ROW0
  31.  
  32. 10 CONSTANT WIDE        \ size of pit in brick positions
  33. 20 CONSTANT DEEP
  34.  
  35. CHAR J    VALUE LEFT-KEY        \ customize if you don't like them
  36. CHAR K    VALUE ROT-KEY
  37. CHAR L    VALUE RIGHT-KEY
  38. BL    VALUE DROP-KEY
  39. CHAR P    VALUE PAUSE-KEY
  40. 12    VALUE REFRESH-KEY
  41. CHAR Q    VALUE QUIT-KEY
  42.  
  43. VARIABLE SCORE
  44. VARIABLE PIECES
  45. VARIABLE LEVELS
  46. VARIABLE DELAY
  47.  
  48. VARIABLE BROW            \ where the brick is
  49. VARIABLE BCOL
  50.  
  51.  
  52. \ stupid random number generator
  53.  
  54. VARIABLE SEED
  55.  
  56. : RANDOMIZE    TIME&DATE + + + + + SEED ! ;
  57.  
  58. : RANDOM    \ max --- n ; return random number < max
  59.         SEED @ 1103515245 * 12345 + [ HEX ] 07FFF [ DECIMAL ] AND
  60.         DUP SEED !  SWAP MOD ;
  61.  
  62.  
  63. \ Access pairs of characters in memory:
  64.  
  65. : 2C@        DUP 1+ C@ SWAP C@ ;
  66. : 2C!        DUP >R C! R> 1+ C! ;
  67.  
  68. : <=        > INVERT ;
  69. : >=        < INVERT ;
  70. : D<>        D= INVERT ;
  71.  
  72.  
  73. \ Drawing primitives:
  74.  
  75. : 2EMIT        EMIT EMIT ;
  76.  
  77. : POSITION    \ row col --- ; cursor to the position in the pit
  78.         2* COL0 + SWAP ROW0 + AT-XY ;
  79.  
  80. : STONE        \ c1 c2 --- ; draw or undraw these two characters
  81.         WIPING @ IF  2DROP 2 SPACES  ELSE  2EMIT  THEN ;
  82.  
  83.  
  84. \ Define the pit where bricks fall into:
  85.  
  86. : DEF-PIT    CREATE    WIDE DEEP * 2* ALLOT
  87.         DOES>    ROT WIDE * ROT + 2* CHARS + ;
  88.  
  89. DEF-PIT PIT
  90.  
  91. : EMPTY-PIT    DEEP 0 DO WIDE 0 DO  EMPTY J I PIT 2C!
  92.         LOOP LOOP ;
  93.  
  94.  
  95. \ Displaying:
  96.  
  97. : DRAW-BOTTOM    \ --- ; redraw the bottom of the pit
  98.         DEEP -1 POSITION
  99.         [CHAR] + DUP STONE
  100.         WIDE 0 DO  [CHAR] = DUP STONE  LOOP
  101.         [CHAR] + DUP STONE ;
  102.  
  103. : DRAW-FRAME    \ --- ; draw the border of the pit
  104.         DEEP 0 DO
  105.             I -1   POSITION [CHAR] | DUP STONE
  106.             I WIDE POSITION [CHAR] | DUP STONE
  107.         LOOP  DRAW-BOTTOM ;
  108.  
  109. : BOTTOM-MSG    \ addr cnt --- ; output a message in the bottom of the pit
  110.         DEEP OVER 2/ WIDE SWAP - 2/ POSITION TYPE ;
  111.  
  112. : DRAW-LINE    \ line ---
  113.         DUP 0 POSITION  WIDE 0 DO  DUP I PIT 2C@ 2EMIT  LOOP  DROP ;
  114.  
  115. : DRAW-PIT    \ --- ; draw the contents of the pit
  116.         DEEP 0 DO  I DRAW-LINE  LOOP ;
  117.  
  118. : SHOW-KEY    \ char --- ; visualization of that character
  119.         DUP BL <
  120.         IF  [CHAR] @ OR  [CHAR] ^ EMIT  EMIT  SPACE
  121.         ELSE  [CHAR] ` EMIT  EMIT  [CHAR] ' EMIT
  122.         THEN ;
  123.  
  124. : SHOW-HELP    \ --- ; display some explanations
  125.         30  1 AT-XY ." ***** T E T R I S *****"
  126.         30  2 AT-XY ." ======================="
  127.         30  4 AT-XY ." Use keys:"
  128.         32  5 AT-XY LEFT-KEY    SHOW-KEY ."  Move left"
  129.         32  6 AT-XY ROT-KEY    SHOW-KEY ."  Rotate"
  130.         32  7 AT-XY RIGHT-KEY    SHOW-KEY ."  Move right"
  131.         32  8 AT-XY DROP-KEY    SHOW-KEY ."  Drop"
  132.         32  9 AT-XY PAUSE-KEY    SHOW-KEY ."  Pause"
  133.         32 10 AT-XY REFRESH-KEY    SHOW-KEY ."  Refresh"
  134.         32 11 AT-XY QUIT-KEY    SHOW-KEY ."  Quit"
  135.         32 13 AT-XY ." -> "
  136.         30 16 AT-XY ." Score:"
  137.         30 17 AT-XY ." Pieces:"
  138.         30 18 AT-XY ." Levels:"
  139.          0 22 AT-XY ."  ======= This program was written 1994 in ANS Forth by Dirk Uwe Zoller ========"
  140.          0 23 at-xy ."  =================== Copy it, port it, play it, enjoy it! =====================" ;
  141.  
  142. : UPDATE-SCORE    \ --- ; display current score
  143.         38 16 AT-XY SCORE @ 3 .R
  144.         38 17 AT-XY PIECES @ 3 .R
  145.         38 18 AT-XY LEVELS @ 3 .R ;
  146.  
  147. : REFRESH    \ --- ; redraw everything on screen
  148.         PAGE DRAW-FRAME DRAW-PIT SHOW-HELP UPDATE-SCORE ;
  149.  
  150.  
  151. \ Define shapes of bricks:
  152.  
  153. : DEF-BRICK    CREATE    4 0 DO
  154.                 ' EXECUTE  0 DO  DUP I CHARS + C@ C,  LOOP DROP
  155.                 REFILL DROP
  156.             LOOP
  157.         DOES>    ROT 4 * ROT + 2* CHARS + ;
  158.  
  159. DEF-BRICK BRICK1    S"         "
  160.             S" ######  "
  161.             S"   ##    "
  162.             S"         "
  163.  
  164. DEF-BRICK BRICK2    S"         "
  165.             S" <><><><>"
  166.             S"         "
  167.             S"         "
  168.  
  169. DEF-BRICK BRICK3    S"         "
  170.             S"   {}{}{}"
  171.             S"   {}    "
  172.             S"         "
  173.  
  174. DEF-BRICK BRICK4    S"         "
  175.             S" ()()()  "
  176.             S"     ()  "
  177.             S"         "
  178.  
  179. DEF-BRICK BRICK5    S"         "
  180.             S"   [][]  "
  181.             S"   [][]  "
  182.             S"         "
  183.  
  184. DEF-BRICK BRICK6    S"         "
  185.             S" @@@@    "
  186.             S"   @@@@  "
  187.             S"         "
  188.  
  189. DEF-BRICK BRICK7    S"         "
  190.             S"   %%%%  "
  191.             S" %%%%    "
  192.             S"         "
  193.  
  194. \ this brick is actually in use:
  195.  
  196. DEF-BRICK BRICK        S"         "
  197.             S"         "
  198.             S"         "
  199.             S"         "
  200.  
  201. DEF-BRICK SCRATCH    S"         "
  202.             S"         "
  203.             S"         "
  204.             S"         "
  205.  
  206. CREATE BRICKS    ' BRICK1 ,  ' BRICK2 ,  ' BRICK3 ,  ' BRICK4 ,
  207.         ' BRICK5 ,  ' BRICK6 ,  ' BRICK7 ,
  208.  
  209. CREATE BRICK-VAL 1 C, 2 C, 3 C, 3 C, 4 C, 5 C, 5 C,
  210.  
  211.  
  212. : IS-BRICK    \ brick --- ; activate a shape of brick
  213.         >BODY ['] BRICK >BODY 32 CMOVE ;
  214.  
  215. : NEW-BRICK    \ --- ; select a new brick by random, count it
  216.         1 PIECES +!  7 RANDOM
  217.         BRICKS OVER CELLS + @ IS-BRICK
  218.         BRICK-VAL SWAP CHARS + C@ SCORE +! ;
  219.  
  220. : ROTLEFT    4 0 DO 4 0 DO
  221.             J I BRICK 2C@  3 I - J SCRATCH 2C!
  222.         LOOP LOOP
  223.         ['] SCRATCH IS-BRICK ;
  224.  
  225. : ROTRIGHT    4 0 DO 4 0 DO
  226.             J I BRICK 2C@  I 3 J - SCRATCH 2C!
  227.         LOOP LOOP
  228.         ['] SCRATCH IS-BRICK ;
  229.  
  230. : DRAW-BRICK    \ row col ---
  231.         4 0 DO 4 0 DO
  232.             J I BRICK 2C@  EMPTY D<>
  233.             IF  OVER J + OVER I +  POSITION
  234.             J I BRICK 2C@  STONE
  235.             THEN
  236.         LOOP LOOP  2DROP ;
  237.  
  238. : SHOW-BRICK    FALSE WIPING ! DRAW-BRICK ;
  239. : HIDE-BRICK    TRUE  WIPING ! DRAW-BRICK ;
  240.  
  241. : PUT-BRICK    \ row col --- ; put the brick into the pit
  242.         4 0 DO 4 0 DO
  243.             J I BRICK 2C@  EMPTY D<>
  244.             IF  OVER J +  OVER I +  PIT
  245.             J I BRICK 2C@  ROT 2C!
  246.             THEN
  247.         LOOP LOOP  2DROP ;
  248.  
  249. : REMOVE-BRICK    \ row col --- ; remove the brick from that position
  250.         4 0 DO 4 0 DO
  251.             J I BRICK 2C@  EMPTY D<>
  252.             IF  OVER J + OVER I + PIT EMPTY ROT 2C!  THEN
  253.         LOOP LOOP  2DROP ;
  254.  
  255. : TEST-BRICK    \ row col --- flag ; could the brick be there?
  256.         4 0 DO 4 0 DO
  257.             J I BRICK 2C@ EMPTY D<>
  258.             IF  OVER J +  OVER I +
  259.             OVER DUP 0< SWAP DEEP >= OR
  260.             OVER DUP 0< SWAP WIDE >= OR
  261.             2SWAP PIT 2C@  EMPTY D<>
  262.             OR OR IF  UNLOOP UNLOOP 2DROP FALSE  EXIT  THEN
  263.             THEN
  264.         LOOP LOOP  2DROP TRUE ;
  265.  
  266. : MOVE-BRICK    \ rows cols --- flag ; try to move the brick
  267.         BROW @ BCOL @ REMOVE-BRICK
  268.         SWAP BROW @ + SWAP BCOL @ + 2DUP TEST-BRICK
  269.         IF  BROW @ BCOL @ HIDE-BRICK
  270.             2DUP BCOL ! BROW !  2DUP SHOW-BRICK PUT-BRICK  TRUE
  271.         ELSE  2DROP BROW @ BCOL @ PUT-BRICK  FALSE
  272.         THEN ;
  273.  
  274. : ROTATE-BRICK    \ flag --- flag ; left/right, success
  275.         BROW @ BCOL @ REMOVE-BRICK
  276.         DUP IF  ROTRIGHT  ELSE  ROTLEFT  THEN
  277.         BROW @ BCOL @ TEST-BRICK
  278.         OVER IF  ROTLEFT  ELSE  ROTRIGHT  THEN
  279.         IF  BROW @ BCOL @ HIDE-BRICK
  280.             IF  ROTRIGHT  ELSE  ROTLEFT  THEN
  281.             BROW @ BCOL @ PUT-BRICK
  282.             BROW @ BCOL @ SHOW-BRICK  TRUE
  283.         ELSE  DROP FALSE  THEN ;
  284.  
  285. : INSERT-BRICK    \ row col --- flag ; introduce a new brick
  286.         2DUP TEST-BRICK
  287.         IF  2DUP BCOL ! BROW !
  288.             2DUP PUT-BRICK  DRAW-BRICK  TRUE
  289.         ELSE  2DROP FALSE  THEN ;
  290.  
  291. : DROP-BRICK    \ --- ; move brick down fast
  292.         BEGIN  1 0 MOVE-BRICK 0=  UNTIL ;
  293.  
  294. : MOVE-LINE    \ from to ---
  295.         OVER 0 PIT  OVER 0 PIT  WIDE 2*  CMOVE  DRAW-LINE
  296.         DUP 0 PIT  WIDE 2*  BLANK  DRAW-LINE ;
  297.  
  298. : LINE-FULL    \ line-no --- flag
  299.         TRUE  WIDE 0
  300.         DO  OVER I PIT 2C@ EMPTY D=
  301.             IF  DROP FALSE  LEAVE  THEN
  302.         LOOP NIP ;
  303.  
  304. : REMOVE-LINES    \ ---
  305.         DEEP DEEP
  306.         BEGIN
  307.             SWAP
  308.             BEGIN  1- DUP 0< IF  2DROP EXIT  THEN  DUP LINE-FULL
  309.             WHILE  1 LEVELS +!  10 SCORE +!  REPEAT
  310.             SWAP 1-
  311.             2DUP <> IF  2DUP MOVE-LINE  THEN
  312.         AGAIN ;
  313.  
  314. : TO-UPPER    \ char --- char ; convert to upper case
  315.         DUP [CHAR] a >= OVER [CHAR] z <= AND
  316.         IF  [ CHAR A CHAR a - ] LITERAL +  THEN ;
  317.  
  318. : DISPATCH    \ key --- flag
  319.         CASE  TO-UPPER
  320.             LEFT-KEY    OF  0 -1 MOVE-BRICK DROP  ENDOF
  321.             RIGHT-KEY    OF  0  1 MOVE-BRICK DROP  ENDOF
  322.             ROT-KEY    OF  0 ROTATE-BRICK DROP  ENDOF
  323.             DROP-KEY    OF  DROP-BRICK  ENDOF
  324.             PAUSE-KEY    OF  S"  Paused " BOTTOM-MSG  KEY DROP
  325.                     DRAW-BOTTOM  ENDOF
  326.             REFRESH-KEY    OF  REFRESH  ENDOF
  327.             QUIT-KEY    OF  FALSE EXIT  ENDOF
  328.         ENDCASE  TRUE ;
  329.  
  330. : INITIALIZE    \ --- ; prepare for playing
  331.         RANDOMIZE EMPTY-PIT REFRESH
  332.         0 SCORE !  0 PIECES !  0 LEVELS !  100 DELAY ! ;
  333.  
  334. : ADJUST-DELAY    \ --- ; make it faster with increasing score
  335.         LEVELS @
  336.         DUP  50 < IF  100 OVER -  ELSE
  337.         DUP 100 < IF   62 OVER 4 / -  ELSE
  338.         DUP 500 < IF   31 OVER 16 / -  ELSE  0  THEN THEN THEN
  339.         DELAY !  DROP ;
  340.  
  341. : PLAY-GAME    \ --- ; play one tetris game
  342.         BEGIN
  343.             NEW-BRICK
  344.             -1 3 INSERT-BRICK
  345.         WHILE
  346.             BEGIN  4 0
  347.             DO  35 13 AT-XY
  348.                 DELAY @ MS KEY?
  349.                 IF  BEGIN  KEY KEY? WHILE  DROP  REPEAT
  350.                 DISPATCH 0=
  351.                 IF  UNLOOP EXIT  THEN
  352.                 THEN
  353.             LOOP
  354.             1 0 MOVE-BRICK  0=
  355.             UNTIL
  356.             REMOVE-LINES
  357.             UPDATE-SCORE
  358.             ADJUST-DELAY
  359.         REPEAT ;
  360.  
  361. FORTH DEFINITIONS
  362.  
  363. : TT        \ --- ; play the tetris game
  364.         INITIALIZE
  365.         S"  Press any key " BOTTOM-MSG KEY DROP DRAW-BOTTOM
  366.         BEGIN
  367.             PLAY-GAME
  368.             S"  Again? " BOTTOM-MSG KEY TO-UPPER [CHAR] Y =
  369.         WHILE  INITIALIZE  REPEAT
  370.         0 23 AT-XY CR ;
  371.  
  372. ONLY FORTH ALSO DEFINITIONS
  373.